﻿

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AnimalFight.Lib.Data;
using AnimalFight.Lib.EventHandlers;
using AnimalFight.Lib.Interfaces;

namespace AnimalFight.Lib
{
    public class BattleField
    {
        private IList<AnimalBase> _animals;
        
        public BattleField()
        {
            this._animals = new List<AnimalBase>();
        }

        public IList<AnimalBase> Animals
        {
            get { return _animals; }
            set { _animals = value; }
        }

        public AnimalBase this[string name]
        {
            get { return this._animals.FirstOrDefault(a => a.Name == name); }

            set
            {
                if (value != null)
                {
                    IAttack attackingAnimal = value as IAttack;
                    if (attackingAnimal != null)
                    {
                        attackingAnimal.AttackEvent += new AttackDelegate(attackingAnimal_AttackEvent);
                    }

                    IDefend defendingAnimal = value as IDefend;
                    if (defendingAnimal != null)
                    {
                        defendingAnimal.DefendEvent += new DefendDelegate(defendingAnimal_DefendEvent);
                    }

                    this._animals.Add(value);
                }
            }
        }

        private void attackingAnimal_AttackEvent(object sender, AttackEventHandler e)
        {
            var animalTarget = this[e.AnimalName];

            if (animalTarget != null)
            {
                IAttackable attackedAnimal = animalTarget as IAttackable;
                if (attackedAnimal != null)
                {
                    Console.WriteLine("{0} attacked with AP = {1}.", e.AnimalName, e.AP );
                    attackedAnimal.Attacked(e.AP);
                }
                else
                {
                    Console.WriteLine("The animal {0} is immortal.", e.AnimalName);
                }
            }
        }

        private void defendingAnimal_DefendEvent(object sender, DefendEventHandler e)
        {
            var defendingAnimal = this[e.AnimalName];

            if (defendingAnimal != null)
            {
                IDefend theAnimal = defendingAnimal as IDefend;
                if (theAnimal != null)
                {
                    theAnimal.IsDefending = true;
                }
                else
                {
                    Console.WriteLine("The animal {0} cannot defend itself.", e.AnimalName);
                }
            }
        }

        public void Command(string animalName, Commands command, string targetName)
        {
            var animal = this[animalName];
            if (animal!=null)
               {
                       switch (command)
                    {
                        case Commands.Attack:
                            if (animal is IAttack)
                            {
                                (animal as IAttack).Attack(targetName);
                            }
                            else
                            {
                                Console.WriteLine("Animal {0} cannot attack.",animalName);
                            }
                            break;
                        case Commands.Defend:
                            if (animal is IDefend)
                            {
                                (animal as IDefend).Defend();
                            }
                            else
                            {
                                Console.WriteLine("Animal {0} cannot defend.",animalName);
                            }
                            break;
                        case Commands.Escape:
                            animal.Escape();
                            break;
                        default:
                            break;
                    }
               }            
            else
               {
                Console.WriteLine("Animal {0} does not exists",animalName);
               }
        }
    }

    public enum Commands { Attack, Defend, Escape }
}